home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / feel0_89.lha / Feel / Modules / purge.em < prev    next >
Lisp/Scheme  |  1993-07-12  |  5KB  |  174 lines

  1. ;; Eulisp Module
  2. ;; Author: pab
  3. ;; File: purge.em
  4. ;; Date: Thu Feb 18 16:05:26 1993
  5. ;;
  6. ;; Project:
  7. ;; Description: 
  8. ;;
  9.  
  10. (defmodule purge
  11.   (eulisp0
  12.    scanners
  13.    describe
  14.    )
  15.   ()
  16.   
  17.  
  18.   (defclass <finalisable-class> (<class>)
  19.     ((count accessor finalisable-slot-count)
  20.      (handle-posn accessor finalisable-handle-posn)
  21.      (proxy accessor proxy-class))
  22.     )
  23.  
  24.   (defclass <finalisable-sd> (<slot-description>)
  25.     ()
  26.     predicate finalisable-sd-p
  27.     )
  28.   
  29.   ;; initializing classes. 
  30.   ;; need to add methods on obj-reader so that we can 
  31.   ;; access the handle safely.
  32.   
  33.   (defmethod initialize ((cl <finalisable-class>) lst)
  34.     (let ((cl (call-next-method)))
  35.       (let ((slot-posn (class-instance-size cl)))
  36.     ((setter class-instance-size) cl (+ slot-posn 1))
  37.     ((setter finalisable-handle-posn) cl slot-posn)
  38.     ((setter proxy-class) cl 
  39.      (scan-args 'proxy-class lst (default-argument cl))))
  40.       cl))
  41.  
  42.   (defmethod compute-initargs ((cl <finalisable-class>) direct inherited)
  43.     (let ((lst (call-next-method)))
  44.       (if (memq 'proxy lst) lst
  45.     (cons 'proxy lst))))
  46.        
  47.   ;; allocating instances -- we make a vector to store the values
  48.   (defmethod allocate ((cl <finalisable-class>) lst)
  49.     (let ((handle (make-vector (finalisable-slot-count cl)))
  50.       (obj (call-next-method)))
  51.       (primitive-set-slot-ref obj (finalisable-handle-posn cl) handle)
  52.       (if (not (scan-args 'proxy lst null-argument))
  53.       (setq *final-lst* 
  54.         (cons (list (make-weak-wrapper obj) 
  55.                 cl
  56.                 handle)
  57.               *final-lst*))
  58.     nil)
  59.       obj))
  60.  
  61.   ;; superclass of all objects (not of itself finalisable)
  62.   (defclass <finalisable> ()
  63.     ()
  64.     )
  65.  
  66.   ;; accessing the handle
  67.  
  68.   (defgeneric obj-handle (obj))
  69.   (defmethod obj-handle ((x <finalisable>))
  70.     (primitive-slot-ref x (finalisable-handle-posn (class-of x))))
  71.   
  72.   (defgeneric (setter obj-handle) (x v)
  73.     method (((x <finalisable>) v)
  74.         (primitive-set-slot-ref x 
  75.                     (finalisable-handle-posn (class-of x))
  76.                     v)))
  77.   ;; Slot access
  78.   (defmethod compute-and-ensure-slot-accessors 
  79.     ((cl <finalisable-class>) effective-sds inherited-sds)
  80.     (labels ((register-sds (lst n)
  81.                (cond ((null lst) 
  82.                   ((setter finalisable-slot-count) cl n))
  83.                  ((finalisable-sd-p (car lst))
  84.                   ((setter slot-description-position) (car lst) n)
  85.                   (register-sds (cdr lst) (+ n 1)))
  86.                  (t (register-sds (cdr lst) n)))))
  87.         (register-sds effective-sds 0))
  88.     (call-next-method))
  89.   
  90.  
  91.   (defmethod compute-primitive-reader-using-slot-description
  92.     ((sd <finalisable-sd>) (cl <finalisable-class>) sds)
  93.     (let ((posn (slot-description-position sd))
  94.       (handle-posn nil))
  95.       (lambda (o)
  96.     (vector-ref (primitive-slot-ref o (finalisable-handle-posn (class-of o))) posn))))
  97.  
  98.   (defmethod compute-primitive-writer-using-slot-description
  99.     ((sd <finalisable-sd>) (cl <finalisable-class>) sds)
  100.     (let ((posn (slot-description-position sd))
  101.       (handle-posn nil))
  102.       (lambda (o v)
  103.     ((setter vector-ref) (primitive-slot-ref o (finalisable-handle-posn (class-of o)))
  104.      posn v))))
  105.  
  106.  
  107.   ;; initializing objects
  108.  
  109.   (defmethod initialize ((x <finalisable>) lst)
  110.     (let ((new (call-next-method)))
  111.       new))
  112.  
  113.   ;; Finalising objects
  114.   (defgeneric finalise (x)
  115.     method (((x <object>))
  116.         (format t "Finalise: ~a~%" x)))
  117.  
  118.   (defun finalise-objects ()
  119.     (format t "Killing objects...~%")
  120.     (mapc (lambda (obj)
  121.         (if (weak-wrapper-ref (car obj))
  122.         nil
  123.           (progn (finalise (make-proxy-object (cadr obj) (caddr obj)))
  124.              ((setter weak-wrapper-ref) (car obj) 'x))))
  125.       *final-lst*))
  126.   
  127.   (defun make-proxy-object (class values)
  128.     (let ((new-cl (proxy-class class)))
  129.       (let ((obj (allocate new-cl
  130.                (list 'proxy t))))
  131.     (mapc (lambda (sd)
  132.         (if (finalisable-sd-p sd)
  133.             ((slot-description-slot-writer 
  134.               (find-slot-description new-cl
  135.                          (slot-description-name sd)))
  136.              obj
  137.              (vector-ref values (slot-description-position sd)))
  138.           nil))
  139.           (class-slot-descriptions class))
  140.     obj)))
  141.   
  142.   (set-post-gc-callback finalise-objects)
  143.  
  144.   ;; List of objects
  145.  
  146.   (deflocal *final-lst* nil)
  147.   )
  148.   ;; poxy example
  149.   
  150.   (defclass <f1> (<finalisable>)
  151.     ;;((s1 slot-class <finalisable-sd> accessor f1s))
  152.     ()
  153.     metaclass <finalisable-class>
  154.     predicate f1p)
  155.  
  156.   ;; less useless example
  157.   ;; probably won't work, but you get the idea
  158.  
  159.   (defclass file (<finalisable>)
  160.     ((h initarg handle accessor file-handle))
  161.     metaclass <finalisable-class>)
  162.  
  163.   (defmethod finalise ((x <file>))
  164.     (close (file-handle file)))
  165.  
  166.   (defmethod initialize ((x <file>) lst)
  167.     (let ((handle (open lst))
  168.       (new (call-next-method)))
  169.       ((setter file-handle) new handle)
  170.       new))
  171.  
  172.   ;; end module
  173.   )
  174.